package blockchain

import (
	"bytes"
	"encoding/gob"
	"goblockchain/constcoe"
	"goblockchain/transaction"
	"goblockchain/utils"
	"io/ioutil"
	"os"
)

// 交易信息池
type TransactionPool struct {
	PubTx []*transaction.Transaction
}

// PubTx用于储存节点收集到的交易信息, 函数实现新交易信息的添加
func (tp *TransactionPool) AddTransaction(tx *transaction.Transaction) {
	tp.PubTx = append(tp.PubTx, tx)
}

/*
每次都将交易信息池保存到constcoe.TransactionPoolFile这个地址中。
0644是指八进制的644（110，100，100），指明了不同用户对文件读写执行的权限。
*/
func (tp *TransactionPool) SaveFile() {
	var content bytes.Buffer
	encoder := gob.NewEncoder(&content)
	err := encoder.Encode(tp)
	utils.Handle(err)
	err = ioutil.WriteFile(constcoe.TransactionPoolFile, content.Bytes(), 0644)
	utils.Handle(err)
}

// 加载交易信息池
func (tp *TransactionPool) LoadFile() error {
	if !utils.FileExists(constcoe.TransactionPoolFile) {
		return nil
	}

	var TransactionPool TransactionPool

	fileContent, err := ioutil.ReadFile(constcoe.TransactionPoolFile)
	if err != nil {
		return err
	}
	decoder := gob.NewDecoder(bytes.NewBuffer(fileContent))
	err = decoder.Decode(&TransactionPool)
	if err != nil {
		return err
	}
	tp.PubTx = TransactionPool.PubTx
	return nil
}

// 创建或者加载一个交易信息池
func CreateTransactionPool() *TransactionPool {
	TransactionPool := TransactionPool{}
	err := TransactionPool.LoadFile()
	utils.Handle(err)
	return &TransactionPool
}

// 通过删除constcoe.TransactionPoolFile，即可实现交易信息池的清空
func RemoveTransactionPoolFile() error {
	err := os.Remove(constcoe.TransactionPoolFile)
	return err
}
